/**
 * Shared metadata + mail sending for the merchant self-service e-mail fields
 * (/users/profile → E-Mails & Billing).
 *
 * EMAIL_FIELDS is the single source of truth for WHICH addresses a merchant
 * may manage, where each one lives (own ad_user row vs the company's
 * c_bpartner row) and what it is used for. The bpartner write keys mirror
 * MERCHANT_PARTNER_FIELDS in merchantPartner.ts (lowercase-first, per the
 * iDempiere REST write-casing rule).
 *
 * Field usage (why the labels/descriptions say what they say):
 *  - eMail (C_BPartner.EMail): general company contact address — ticket
 *    "your action required" notifications go here
 *    (requests/[id]/action-notification.post.ts) and it is the fallback
 *    whenever a more specific address below is empty.
 *  - eMailInvoice (C_BPartner.EMail_Invoice): invoices are sent here.
 *  - returnEmail (C_BPartner.return_email): customer-return notifications
 *    (mobile/send-return-notification.post.ts) + CC on ticket action mails.
 *  - freightServiceSenderMail (C_BPartner.freight_service_sender_mail):
 *    passed to the freight service (DHL/DPD) as the sender contact e-mail
 *    when shipping labels are created (commission/parcels/**).
 *  - userEmail (AD_User.EMail): the user's own account address.
 */

import nodemailer from 'nodemailer'

export const APP_BASE_URL = 'https://app.logship.de'

// Same plausibility check on client and server. Deliberately simple: one @,
// no whitespace, a dot in the domain. iDempiere itself stores plain strings.
export const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
export const isValidEmailSyntax = (value: string) =>
  EMAIL_REGEX.test(value) && value.length <= 254

export interface EmailFieldDef {
  kind: 'bpartner' | 'aduser'
  writeKey: string        // lowercase-first iDempiere REST write key
  required: boolean       // required fields cannot be cleared to ''
  labelDe: string
  labelEn: string
}

export const EMAIL_FIELDS: Record<string, EmailFieldDef> = {
  userEmail: {
    kind: 'aduser', writeKey: 'eMail', required: true,
    labelDe: 'Eigene Konto-E-Mail', labelEn: 'Your account e-mail'
  },
  eMail: {
    kind: 'bpartner', writeKey: 'eMail', required: true,
    labelDe: 'Allgemeine Kontakt-E-Mail', labelEn: 'General contact e-mail'
  },
  eMailInvoice: {
    kind: 'bpartner', writeKey: 'eMail_Invoice', required: false,
    labelDe: 'Rechnungs-E-Mail', labelEn: 'Invoice e-mail'
  },
  returnEmail: {
    kind: 'bpartner', writeKey: 'return_email', required: false,
    labelDe: 'Retouren-E-Mail', labelEn: 'Return e-mail'
  },
  freightServiceSenderMail: {
    kind: 'bpartner', writeKey: 'freight_service_sender_mail', required: false,
    labelDe: 'Versanddienstleister Absender-E-Mail', labelEn: 'Freight service sender e-mail'
  }
}

const escapeHtml = (s: string) => String(s || '')
  .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
  .replace(/"/g, '&quot;').replace(/'/g, '&#39;')

const buildVerificationHtml = (
  fieldLabel: string, oldEmail: string, newEmail: string, link: string, isGerman: boolean
) => {
  const title = isGerman ? 'Neue E-Mail-Adresse bestätigen' : 'Confirm your new e-mail address'
  const intro = isGerman
    ? 'Für Ihr LogShip-Konto wurde eine Änderung der folgenden E-Mail-Adresse angefordert. Die Änderung wird erst wirksam, wenn Sie sie über den Button unten bestätigen.'
    : 'A change of the following e-mail address was requested for your LogShip account. The change only takes effect once you confirm it via the button below.'
  const fieldLbl = isGerman ? 'Adresse' : 'Address'
  const oldLbl = isGerman ? 'Bisher' : 'Current'
  const newLbl = isGerman ? 'Neu' : 'New'
  const cta = isGerman ? 'E-Mail-Adresse bestätigen' : 'Confirm e-mail address'
  const expiry = isGerman
    ? 'Der Link ist 48 Stunden gültig. Bis zur Bestätigung bleibt die bisherige Adresse aktiv.'
    : 'The link is valid for 48 hours. Until confirmed, the current address stays active.'
  const ignore = isGerman
    ? 'Wenn Sie diese Änderung nicht angefordert haben, können Sie diese E-Mail ignorieren — es wird nichts geändert.'
    : 'If you did not request this change, you can ignore this e-mail — nothing will be changed.'

  return `<!DOCTYPE html><html><head><meta charset="utf-8"></head>
<body style="margin:0;padding:0;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:1.6;color:#333;background:#f4f4f4;">
<table width="100%" cellpadding="0" cellspacing="0" style="background:#f4f4f4;"><tr><td style="padding:20px 0;">
<table width="600" cellpadding="0" cellspacing="0" style="margin:0 auto;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 2px 4px rgba(0,0,0,0.1);">
<tr><td style="background:#0d6efd;padding:30px 40px;text-align:center;">
<h1 style="margin:0;color:#fff;font-size:22px;">${title}</h1>
</td></tr>
<tr><td style="padding:32px 40px;">
<p style="margin:0 0 16px 0;">${intro}</p>
<table cellpadding="0" cellspacing="0" style="width:100%;border-collapse:collapse;margin:16px 0;border:1px solid #e5e7eb;border-radius:6px;">
<tr style="background:#f9fafb;"><td style="padding:10px 14px;border-bottom:1px solid #e5e7eb;font-weight:600;width:120px;">${fieldLbl}</td><td style="padding:10px 14px;border-bottom:1px solid #e5e7eb;">${escapeHtml(fieldLabel)}</td></tr>
<tr><td style="padding:10px 14px;border-bottom:1px solid #e5e7eb;font-weight:600;">${oldLbl}</td><td style="padding:10px 14px;border-bottom:1px solid #e5e7eb;">${escapeHtml(oldEmail) || '—'}</td></tr>
<tr><td style="padding:10px 14px;font-weight:600;">${newLbl}</td><td style="padding:10px 14px;"><strong>${escapeHtml(newEmail)}</strong></td></tr>
</table>
<p style="text-align:center;margin:24px 0;"><a href="${link}" style="display:inline-block;padding:12px 28px;background:#0d6efd;color:#fff;text-decoration:none;border-radius:6px;font-weight:600;">${cta}</a></p>
<p style="margin:16px 0 0 0;font-size:12px;color:#666;">${expiry}</p>
</td></tr>
<tr><td style="background:#f8f9fa;padding:16px 40px;text-align:center;border-top:1px solid #eee;">
<p style="margin:0;font-size:12px;color:#888;">${ignore}</p>
</td></tr>
</table></td></tr></table></body></html>`
}

/**
 * Sends the confirmation link to the NEW address. Throws on transport
 * failure — the caller must then discard the pending row so the UI doesn't
 * show a "waiting for confirmation" that can never arrive.
 */
export const sendVerificationEmail = async (opts: {
  fieldKey: string
  oldEmail: string
  newEmail: string
  token: string
  language: string
}) => {
  const def = EMAIL_FIELDS[opts.fieldKey]
  if (!def) throw new Error(`Unknown email field: ${opts.fieldKey}`)
  const isGerman = String(opts.language || 'de_DE').startsWith('de')
  const label = isGerman ? def.labelDe : def.labelEn
  const link = `${APP_BASE_URL}/verify-email?token=${encodeURIComponent(opts.token)}`

  const transporter = nodemailer.createTransport({
    host: 'localhost', port: 25, secure: false, tls: { rejectUnauthorized: false }
  })
  await transporter.sendMail({
    from: 'no-reply@logyou.de',
    to: opts.newEmail,
    subject: isGerman
      ? `Bitte bestätigen Sie Ihre neue E-Mail-Adresse (${label})`
      : `Please confirm your new e-mail address (${label})`,
    html: buildVerificationHtml(label, opts.oldEmail, opts.newEmail, link, isGerman)
  })
}
